// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.ai.states;

import fmod.fmod.FMODManager;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjglx.input.Keyboard;
import zombie.Lua.LuaEventManager;
import zombie.Lua.LuaHookManager;
import zombie.ai.State;
import zombie.audio.parameters.ParameterMeleeHitSurface;
import zombie.characterTextures.BloodBodyPartType;
import zombie.characters.Faction;
import zombie.characters.HitReactionNetworkAI;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoLivingCharacter;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.characters.BodyDamage.BodyPart;
import zombie.characters.BodyDamage.BodyPartType;
import zombie.characters.Moodles.MoodleType;
import zombie.characters.skills.PerkFactory;
import zombie.core.Core;
import zombie.core.Rand;
import zombie.core.math.PZMath;
import zombie.core.skinnedmodel.advancedanimation.AnimEvent;
import zombie.core.skinnedmodel.animation.AnimationPlayer;
import zombie.core.skinnedmodel.model.Model;
import zombie.debug.DebugLog;
import zombie.debug.DebugOptions;
import zombie.debug.DebugType;
import zombie.inventory.InventoryItem;
import zombie.inventory.InventoryItemFactory;
import zombie.inventory.types.Clothing;
import zombie.inventory.types.HandWeapon;
import zombie.inventory.types.WeaponType;
import zombie.iso.IsoCell;
import zombie.iso.IsoDirections;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoMovingObject;
import zombie.iso.IsoObject;
import zombie.iso.IsoUtils;
import zombie.iso.IsoWorld;
import zombie.iso.LosUtil;
import zombie.iso.Vector2;
import zombie.iso.Vector3;
import zombie.iso.areas.NonPvpZone;
import zombie.iso.objects.IsoDoor;
import zombie.iso.objects.IsoThumpable;
import zombie.iso.objects.IsoTree;
import zombie.iso.objects.IsoWindow;
import zombie.iso.objects.IsoZombieGiblets;
import zombie.iso.objects.interfaces.Thumpable;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerOptions;
import zombie.network.packets.hit.AttackVars;
import zombie.network.packets.hit.HitInfo;
import zombie.popman.ObjectPool;
import zombie.scripting.objects.VehicleScript;
import zombie.ui.MoodlesUI;
import zombie.ui.UIManager;
import zombie.util.StringUtils;
import zombie.util.Type;
import zombie.vehicles.BaseVehicle;
import zombie.vehicles.PolygonalMap2;
import zombie.vehicles.VehiclePart;
import zombie.vehicles.VehicleWindow;

public final class SwipeStatePlayer extends State {
    private static final SwipeStatePlayer _instance = new SwipeStatePlayer();
    static final Integer PARAM_LOWER_CONDITION = 0;
    static final Integer PARAM_ATTACKED = 1;
    private static final ArrayList<HitInfo> HitList2 = new ArrayList();
    private static final Vector2 tempVector2_1 = new Vector2();
    private static final Vector2 tempVector2_2 = new Vector2();
    private final ArrayList<Float> dotList = new ArrayList();
    private boolean bHitOnlyTree;
    public final ObjectPool<HitInfo> hitInfoPool = new ObjectPool<>(HitInfo::new);
    private static final SwipeStatePlayer.CustomComparator Comparator = new SwipeStatePlayer.CustomComparator();
    static final Vector3 tempVector3_1 = new Vector3();
    static final Vector3 tempVector3_2 = new Vector3();
    static final Vector3 tempVectorBonePos = new Vector3();
    static final ArrayList<IsoMovingObject> movingStatic = new ArrayList();
    private final Vector4f tempVector4f = new Vector4f();
    private final SwipeStatePlayer.WindowVisitor windowVisitor = new SwipeStatePlayer.WindowVisitor();

    public static SwipeStatePlayer instance() {
        return _instance;
    }

    public static void WeaponLowerCondition(HandWeapon weapon, IsoGameCharacter owner) {
        if (weapon.getUses() > 1) {
            weapon.Use();
            InventoryItem inventoryItem = InventoryItemFactory.CreateItem(weapon.getFullType());
            inventoryItem.setCondition(weapon.getCondition() - 1);
            weapon.getContainer().AddItem(inventoryItem);
            owner.setPrimaryHandItem(inventoryItem);
        } else {
            weapon.setCondition(weapon.getCondition() - 1);
        }
    }

    private static HandWeapon GetWeapon(IsoGameCharacter isoGameCharacter) {
        HandWeapon handWeapon = isoGameCharacter.getUseHandWeapon();
        if (((IsoLivingCharacter)isoGameCharacter).bDoShove || isoGameCharacter.isForceShove()) {
            handWeapon = ((IsoLivingCharacter)isoGameCharacter).bareHands;
        }

        return handWeapon;
    }

    private void doAttack(IsoPlayer isoPlayer, float _float, boolean _boolean, String string, AttackVars attackVars) {
        isoPlayer.setForceShove(_boolean);
        isoPlayer.setClickSound(string);
        if (_boolean) {
            _float *= 2.0F;
        }

        if (_float > 90.0F) {
            _float = 90.0F;
        }

        _float /= 25.0F;
        isoPlayer.useChargeDelta = _float;
        Object object = isoPlayer.getPrimaryHandItem();
        if (object == null || !(object instanceof HandWeapon) || _boolean || attackVars.bDoShove) {
            object = isoPlayer.bareHands;
        }

        if (object instanceof HandWeapon) {
            isoPlayer.setUseHandWeapon((HandWeapon)object);
            if (isoPlayer.PlayerIndex == 0 && isoPlayer.JoypadBind == -1 && UIManager.getPicked() != null && (!GameClient.bClient || isoPlayer.isLocalPlayer())
                )
             {
                if (UIManager.getPicked().tile instanceof IsoMovingObject) {
                    isoPlayer.setAttackTargetSquare(((IsoMovingObject)UIManager.getPicked().tile).getCurrentSquare());
                } else {
                    isoPlayer.setAttackTargetSquare(UIManager.getPicked().square);
                }
            }

            isoPlayer.setRecoilDelay((float)attackVars.recoilDelay);
            if (_boolean) {
                isoPlayer.setRecoilDelay(10.0F);
            }
        }
    }

    @Override
    public void enter(IsoGameCharacter owner) {
        if ("HitReaction".equals(owner.getHitReaction())) {
            owner.clearVariable("HitReaction");
        }

        UIManager.speedControls.SetCurrentGameSpeed(1);
        HashMap hashMap = owner.getStateMachineParams(this);
        hashMap.put(PARAM_LOWER_CONDITION, Boolean.FALSE);
        hashMap.put(PARAM_ATTACKED, Boolean.FALSE);
        if (!(owner instanceof IsoPlayer) || !((IsoPlayer)owner).bRemote) {
            owner.updateRecoilVar();
        }

        if ("Auto".equals(owner.getVariableString("FireMode"))) {
            owner.setVariable("autoShootSpeed", 4.0F * zombie.GameTime.getAnimSpeedFix());
            owner.setVariable("autoShootVarY", 0.0F);
            if (System.currentTimeMillis() - owner.lastAutomaticShoot < 600L) {
                owner.shootInARow++;
                float _float = Math.max(0.0F, 1.0F - (float)owner.shootInARow / 20.0F);
                owner.setVariable("autoShootVarX", _float);
            } else {
                owner.setVariable("autoShootVarX", 1.0F);
                owner.shootInARow = 0;
            }

            owner.lastAutomaticShoot = System.currentTimeMillis();
        }

        IsoPlayer isoPlayer = (IsoPlayer)owner;
        owner.setVariable("ShotDone", false);
        owner.setVariable("ShoveAnim", false);
        this.CalcAttackVars((IsoLivingCharacter)owner, isoPlayer.attackVars);
        this.doAttack(isoPlayer, 2.0F, owner.isForceShove(), owner.getClickSound(), isoPlayer.attackVars);
        HandWeapon handWeapon = owner.getUseHandWeapon();
        if (!GameClient.bClient || isoPlayer.isLocalPlayer()) {
            owner.setVariable("AimFloorAnim", isoPlayer.attackVars.bAimAtFloor);
        }

        LuaEventManager.triggerEvent("OnWeaponSwing", owner, handWeapon);
        if (LuaHookManager.TriggerHook("WeaponSwing", owner, handWeapon)) {
            owner.getStateMachine().revertToPreviousState(this);
        }

        owner.StopAllActionQueue();
        if (((IsoPlayer)owner).isLocalPlayer()) {
            IsoWorld.instance.CurrentCell.setDrag(null, ((IsoPlayer)owner).PlayerIndex);
        }

        handWeapon = isoPlayer.attackVars.getWeapon(isoPlayer);
        isoPlayer.setAimAtFloor(isoPlayer.attackVars.bAimAtFloor);
        boolean _boolean = isoPlayer.bDoShove;
        isoPlayer.setDoShove(isoPlayer.attackVars.bDoShove);
        isoPlayer.useChargeDelta = isoPlayer.attackVars.useChargeDelta;
        isoPlayer.targetOnGround = (IsoGameCharacter)isoPlayer.attackVars.targetOnGround.getMovingObject();
        if (!isoPlayer.bDoShove && !_boolean && isoPlayer.getClickSound() == null && handWeapon.getPhysicsObject() == null && !handWeapon.isRanged()) {
        }

        if (GameClient.bClient && owner == IsoPlayer.getInstance()) {
            GameClient.instance.sendPlayer((IsoPlayer)owner);
        }

        if (!isoPlayer.bDoShove && !_boolean && !handWeapon.isRanged() && isoPlayer.isLocalPlayer()) {
            owner.clearVariable("PlayedSwingSound");
        } else if ((isoPlayer.bDoShove || _boolean) && isoPlayer.isLocalPlayer()) {
            if (isoPlayer.targetOnGround != null) {
                owner.playSound("AttackStomp");
            } else {
                owner.playSound("AttackShove");
            }
        }
    }

    @Override
    public void execute(IsoGameCharacter owner) {
        owner.StopAllActionQueue();
    }

    private int DoSwingCollisionBoneCheck(IsoGameCharacter isoGameCharacter0, HandWeapon handWeapon, IsoGameCharacter isoGameCharacter1, int int0, float float2) {
        movingStatic.clear();
        float float0 = handWeapon.WeaponLength;
        float0 += 0.5F;
        if (isoGameCharacter0.isAimAtFloor() && ((IsoLivingCharacter)isoGameCharacter0).bDoShove) {
            float0 = 0.3F;
        }

        Model.BoneToWorldCoords(isoGameCharacter1, int0, tempVectorBonePos);

        for (int int1 = 1; int1 <= 10; int1++) {
            float float1 = (float)int1 / 10.0F;
            tempVector3_1.x = isoGameCharacter0.x;
            tempVector3_1.y = isoGameCharacter0.y;
            tempVector3_1.z = isoGameCharacter0.z;
            tempVector3_1.x = tempVector3_1.x + isoGameCharacter0.getForwardDirection().x * float0 * float1;
            tempVector3_1.y = tempVector3_1.y + isoGameCharacter0.getForwardDirection().y * float0 * float1;
            tempVector3_1.x = tempVectorBonePos.x - tempVector3_1.x;
            tempVector3_1.y = tempVectorBonePos.y - tempVector3_1.y;
            tempVector3_1.z = 0.0F;
            boolean _boolean = tempVector3_1.getLength() < float2;
            if (_boolean) {
                return int0;
            }
        }

        return -1;
    }

    @Override
    public void animEvent(IsoGameCharacter owner, AnimEvent event) {
        HashMap hashMap = owner.getStateMachineParams(this);
        if (event.m_EventName.equalsIgnoreCase("ActiveAnimFinishing") || event.m_EventName.equalsIgnoreCase("NonLoopedAnimFadeOut")) {
            boolean _boolean = hashMap.get(PARAM_LOWER_CONDITION) == Boolean.TRUE;
            if (_boolean && !owner.isRangedWeaponEmpty()) {
                hashMap.put(PARAM_LOWER_CONDITION, Boolean.FALSE);
                HandWeapon handWeapon0 = GetWeapon(owner);
                int _int = handWeapon0.getConditionLowerChance();
                if (owner instanceof IsoPlayer && "charge".equals(((IsoPlayer)owner).getAttackType())) {
                    _int = (int)((double)_int / 1.5);
                }

                if (Rand.Next(_int + owner.getMaintenanceMod() * 2) == 0) {
                    WeaponLowerCondition(handWeapon0, owner);
                } else if (Rand.NextBool(2) && !handWeapon0.isRanged() && WeaponType.getWeaponType(owner) != WeaponType.barehand) {
                    if (handWeapon0.isTwoHandWeapon()
                        && (owner.getPrimaryHandItem() != handWeapon0 || owner.getSecondaryHandItem() != handWeapon0)
                        && Rand.NextBool(3)) {
                        return;
                    }

                    owner.getXp().AddXP(PerkFactory.Perks.Maintenance, 1.0F);
                }
            }
        }

        if (event.m_EventName.equalsIgnoreCase("AttackAnim")) {
            owner.setAttackAnim(Boolean.parseBoolean(event.m_ParameterValue));
        }

        if (event.m_EventName.equalsIgnoreCase("BlockTurn")) {
            owner.setIgnoreMovement(Boolean.parseBoolean(event.m_ParameterValue));
        }

        if (event.m_EventName.equalsIgnoreCase("ShoveAnim")) {
            owner.setVariable("ShoveAnim", Boolean.parseBoolean(event.m_ParameterValue));
        }

        if (event.m_EventName.equalsIgnoreCase("StompAnim")) {
            owner.setVariable("StompAnim", Boolean.parseBoolean(event.m_ParameterValue));
        }

        HandWeapon handWeapon1 = GetWeapon(owner);
        if (event.m_EventName.equalsIgnoreCase("AttackCollisionCheck")
            && hashMap.get(PARAM_ATTACKED) == Boolean.FALSE
            && owner instanceof IsoPlayer
            && ((IsoPlayer)owner).isLocalPlayer()) {
            this.ConnectSwing(owner, handWeapon1);
        }

        if (event.m_EventName.equalsIgnoreCase("BlockMovement") && zombie.SandboxOptions.instance.AttackBlockMovements.getValue()) {
            owner.setVariable("SlowingMovement", Boolean.parseBoolean(event.m_ParameterValue));
        }

        if (event.m_EventName.equalsIgnoreCase("WeaponEmptyCheck") && owner.getClickSound() != null) {
            if (owner instanceof IsoPlayer && !((IsoPlayer)owner).isLocalPlayer()) {
                return;
            }

            owner.playSound(owner.getClickSound());
            owner.setRecoilDelay(10.0F);
        }

        if (event.m_EventName.equalsIgnoreCase("ShotDone") && handWeapon1 != null && handWeapon1.isRackAfterShoot()) {
            owner.setVariable("ShotDone", true);
        }

        if (event.m_EventName.equalsIgnoreCase("SetVariable") && event.m_ParameterValue.startsWith("ShotDone=")) {
            owner.setVariable("ShotDone", owner.getVariableBoolean("ShotDone") && handWeapon1 != null && handWeapon1.isRackAfterShoot());
        }

        if (event.m_EventName.equalsIgnoreCase("playRackSound")) {
            if (owner instanceof IsoPlayer && !((IsoPlayer)owner).isLocalPlayer()) {
                return;
            }

            owner.playSound(handWeapon1.getRackSound());
        }

        if (event.m_EventName.equalsIgnoreCase("playClickSound")) {
            if (owner instanceof IsoPlayer && !((IsoPlayer)owner).isLocalPlayer()) {
                return;
            }

            owner.playSound(handWeapon1.getClickSound());
        }

        if (event.m_EventName.equalsIgnoreCase("PlaySwingSound")) {
            if (owner instanceof IsoPlayer && !((IsoPlayer)owner).isLocalPlayer()) {
                return;
            }

            if (handWeapon1 == null) {
                return;
            }

            if (owner.getVariableBoolean("PlayedSwingSound")) {
                return;
            }

            owner.setVariable("PlayedSwingSound", true);
            if (!StringUtils.isNullOrWhitespace(event.m_ParameterValue)) {
                String string = handWeapon1.getSoundByID(event.m_ParameterValue);
                if (string != null) {
                    owner.playSound(string);
                    return;
                }
            }

            owner.playSound(handWeapon1.getSwingSound());
        }

        if (event.m_EventName.equalsIgnoreCase("SetMeleeDelay")) {
            owner.setMeleeDelay(PZMath.tryParseFloat(event.m_ParameterValue, 0.0F));
        }

        if (event.m_EventName.equalsIgnoreCase("SitGroundStarted")) {
            owner.setVariable("SitGroundAnim", "Idle");
        }
    }

    @Override
    public void exit(IsoGameCharacter owner) {
        HashMap hashMap = owner.getStateMachineParams(this);
        owner.setSprinting(false);
        ((IsoPlayer)owner).setForceSprint(false);
        owner.setIgnoreMovement(false);
        owner.setVariable("ShoveAnim", false);
        owner.setVariable("StompAnim", false);
        owner.setAttackAnim(false);
        owner.setVariable("AimFloorAnim", false);
        ((IsoPlayer)owner).setBlockMovement(false);
        if (owner.isAimAtFloor() && ((IsoLivingCharacter)owner).bDoShove) {
            Clothing clothing = (Clothing)owner.getWornItem("Shoes");
            int _int = 10;
            if (clothing == null) {
                _int = 3;
            } else {
                _int += clothing.getConditionLowerChance() / 2;
                if (Rand.Next(clothing.getConditionLowerChance()) == 0) {
                    clothing.setCondition(clothing.getCondition() - 1);
                }
            }

            if (Rand.Next(_int) == 0) {
                if (clothing == null) {
                    owner.getBodyDamage().getBodyPart(BodyPartType.Foot_R).AddDamage((float)Rand.Next(5, 10));
                    owner.getBodyDamage()
                        .getBodyPart(BodyPartType.Foot_R)
                        .setAdditionalPain(owner.getBodyDamage().getBodyPart(BodyPartType.Foot_R).getAdditionalPain() + (float)Rand.Next(5, 10));
                } else {
                    owner.getBodyDamage().getBodyPart(BodyPartType.Foot_R).AddDamage((float)Rand.Next(1, 5));
                    owner.getBodyDamage()
                        .getBodyPart(BodyPartType.Foot_R)
                        .setAdditionalPain(owner.getBodyDamage().getBodyPart(BodyPartType.Foot_R).getAdditionalPain() + (float)Rand.Next(1, 5));
                }
            }
        }

        HandWeapon handWeapon = GetWeapon(owner);
        owner.clearVariable("ZombieHitReaction");
        ((IsoPlayer)owner).attackStarted = false;
        ((IsoPlayer)owner).setAttackType(null);
        ((IsoLivingCharacter)owner).setDoShove(false);
        owner.clearVariable("RackWeapon");
        owner.clearVariable("bShoveAiming");
        owner.clearVariable("PlayedSwingSound");
        boolean _boolean = hashMap.get(PARAM_ATTACKED) == Boolean.TRUE;
        if (handWeapon != null && (handWeapon.getCondition() <= 0 || _boolean && handWeapon.isUseSelf())) {
            owner.removeFromHands(handWeapon);
            if (DebugOptions.instance.MultiplayerAutoEquip.getValue() && handWeapon.getPhysicsObject() != null) {
                owner.setPrimaryHandItem(owner.getInventory().getItemFromType(handWeapon.getType()));
            }

            owner.getInventory().setDrawDirty(true);
        }

        if (owner.isRangedWeaponEmpty()) {
            owner.setRecoilDelay(10.0F);
        }

        owner.setRangedWeaponEmpty(false);
        owner.setForceShove(false);
        owner.setClickSound(null);
        if (_boolean) {
            LuaEventManager.triggerEvent("OnPlayerAttackFinished", owner, handWeapon);
        }

        owner.hitList.clear();
        owner.attackVars.clear();
    }

    public void CalcAttackVars(IsoLivingCharacter owner, AttackVars vars) {
        HandWeapon handWeapon = Type.tryCastTo(owner.getPrimaryHandItem(), HandWeapon.class);
        if (handWeapon != null && handWeapon.getOtherHandRequire() != null) {
            InventoryItem inventoryItem = owner.getSecondaryHandItem();
            if (inventoryItem == null || !inventoryItem.getType().equals(handWeapon.getOtherHandRequire())) {
                handWeapon = null;
            }
        }

        if (!GameClient.bClient || owner.isLocal()) {
            boolean boolean0 = owner.isAttackAnim() || owner.getVariableBoolean("ShoveAnim") || owner.getVariableBoolean("StompAnim");
            vars.setWeapon(handWeapon == null ? owner.bareHands : handWeapon);
            vars.targetOnGround.setMovingObject(null);
            vars.bAimAtFloor = false;
            vars.bCloseKill = false;
            vars.bDoShove = owner.bDoShove;
            if (!boolean0) {
                owner.setVariable("ShoveAimX", 0.5F);
                owner.setVariable("ShoveAimY", 1.0F);
                if (vars.bDoShove && owner.getVariableBoolean("isMoving")) {
                    owner.setVariable("ShoveAim", true);
                } else {
                    owner.setVariable("ShoveAim", false);
                }
            }

            vars.useChargeDelta = owner.useChargeDelta;
            vars.recoilDelay = 0;
            if (vars.getWeapon(owner) == owner.bareHands || vars.bDoShove || owner.isForceShove()) {
                vars.bDoShove = true;
                vars.bAimAtFloor = false;
                vars.setWeapon(owner.bareHands);
            }

            this.calcValidTargets(owner, vars.getWeapon(owner), true, vars.targetsProne, vars.targetsStanding);
            HitInfo hitInfo0 = vars.targetsStanding.isEmpty() ? null : (HitInfo)vars.targetsStanding.get(0);
            HitInfo hitInfo1 = vars.targetsProne.isEmpty() ? null : (HitInfo)vars.targetsProne.get(0);
            if (this.isProneTargetBetter(owner, hitInfo0, hitInfo1)) {
                hitInfo0 = null;
            }

            if (!boolean0) {
                owner.setAimAtFloor(false);
            }

            float _floatx = Float.MAX_VALUE;
            if (hitInfo0 != null) {
                if (!boolean0) {
                    owner.setAimAtFloor(false);
                }

                vars.bAimAtFloor = false;
                vars.targetOnGround.setMovingObject(null);
                _floatx = hitInfo0.distSq;
            } else if (hitInfo1 != null && (Core.OptionAutoProneAtk || owner.bDoShove)) {
                if (!boolean0) {
                    owner.setAimAtFloor(true);
                }

                vars.bAimAtFloor = true;
                vars.targetOnGround.setMovingObject(hitInfo1.getObject());
            }

            if (!(_floatx >= vars.getWeapon(owner).getMinRange() * vars.getWeapon(owner).getMinRange())
                && (hitInfo0 == null || !this.isWindowBetween(owner, hitInfo0.getObject()))) {
                if (owner.getStats().NumChasingZombies <= 1 && WeaponType.getWeaponType(owner) == WeaponType.knife) {
                    vars.bCloseKill = true;
                    return;
                }

                vars.bDoShove = true;
                IsoPlayer isoPlayer = Type.tryCastTo(owner, IsoPlayer.class);
                if (isoPlayer != null && !isoPlayer.isAuthorizeShoveStomp()) {
                    vars.bDoShove = false;
                }

                vars.bAimAtFloor = false;
                if (owner.bareHands.getSwingAnim() != null) {
                    vars.useChargeDelta = 3.0F;
                }
            }

            int int0 = Core.getInstance().getKey("ManualFloorAtk");
            int int1 = Core.getInstance().getKey("Sprint");
            boolean boolean1 = owner.getVariableBoolean("StartedAttackWhileSprinting");
            if (Keyboard.isKeyDown(int0) && (int0 != int1 || !boolean1)) {
                vars.bAimAtFloor = true;
                vars.bDoShove = false;
                owner.setDoShove(false);
            }

            if (vars.getWeapon(owner).isRanged()) {
                int int2 = vars.getWeapon(owner).getRecoilDelay();
                Float _floatx = (float)int2 * (1.0F - (float)owner.getPerkLevel(PerkFactory.Perks.Aiming) / 30.0F);
                vars.recoilDelay = _floatx.intValue();
                owner.setVariable("singleShootSpeed", (0.8F + (float)owner.getPerkLevel(PerkFactory.Perks.Aiming) / 10.0F) * zombie.GameTime.getAnimSpeedFix());
            }
        }
    }

    public void calcValidTargets(
        IsoLivingCharacter owner, HandWeapon weapon, boolean extraRange, ArrayList<HitInfo> targetsProne, ArrayList<HitInfo> targetsStanding
    ) {
        this.hitInfoPool.release(targetsProne);
        this.hitInfoPool.release(targetsStanding);
        targetsProne.clear();
        targetsStanding.clear();
        float float0 = Core.getInstance().getIgnoreProneZombieRange();
        float float1 = weapon.getMaxRange() * weapon.getRangeMod(owner);
        float float2 = Math.max(float0, float1 + (extraRange ? 1.0F : 0.0F));
        ArrayList arrayList = IsoWorld.instance.CurrentCell.getObjectList();

        for (int _int = 0; _int < arrayList.size(); _int++) {
            IsoMovingObject isoMovingObject = (IsoMovingObject)arrayList.get(_int);
            HitInfo hitInfo = this.calcValidTarget(owner, weapon, isoMovingObject, float2);
            if (hitInfo != null) {
                if (isStanding(isoMovingObject)) {
                    targetsStanding.add(hitInfo);
                } else {
                    targetsProne.add(hitInfo);
                }
            }
        }

        if (!targetsProne.isEmpty() && this.shouldIgnoreProneZombies(owner, targetsStanding, float0)) {
            this.hitInfoPool.release(targetsProne);
            targetsProne.clear();
        }

        float float3 = weapon.getMinAngle();
        float float4 = weapon.getMaxAngle();
        if (weapon.isRanged()) {
            float3 -= weapon.getAimingPerkMinAngleModifier() * ((float)owner.getPerkLevel(PerkFactory.Perks.Aiming) / 2.0F);
        }

        this.removeUnhittableTargets(owner, weapon, float3, float4, extraRange, targetsStanding);
        float3 = weapon.getMinAngle();
        float3 = (float)((double)float3 / 1.5);
        this.removeUnhittableTargets(owner, weapon, float3, float4, extraRange, targetsProne);
        targetsStanding.sort(Comparator);
        targetsProne.sort(Comparator);
    }

    private boolean shouldIgnoreProneZombies(IsoGameCharacter isoGameCharacter, ArrayList<HitInfo> arrayList, float _float) {
        if (_float <= 0.0F) {
            return false;
        } else {
            boolean boolean0 = isoGameCharacter.isInvisible() || isoGameCharacter instanceof IsoPlayer && ((IsoPlayer)isoGameCharacter).isGhostMode();

            for (int int0 = 0; int0 < arrayList.size(); int0++) {
                HitInfo hitInfo = (HitInfo)arrayList.get(int0);
                IsoZombie isoZombie = Type.tryCastTo(hitInfo.getObject(), IsoZombie.class);
                if ((isoZombie == null || isoZombie.target != null || boolean0) && !(hitInfo.distSq > _float * _float)) {
                    int int1 = (int)isoGameCharacter.z;
                    boolean boolean1 = PolygonalMap2.instance
                        .lineClearCollide(
                            isoGameCharacter.x, isoGameCharacter.y, hitInfo.getObject().x, hitInfo.getObject().y, int1, isoGameCharacter, false, true
                        );
                    if (!boolean1) {
                        return true;
                    }
                }
            }

            return false;
        }
    }

    private boolean isUnhittableTarget(IsoGameCharacter isoGameCharacter, HandWeapon handWeapon, float float1, float float0, HitInfo hitInfo, boolean _boolean) {
        if (!(hitInfo.dot < float1) && !(hitInfo.dot > float0)) {
            Vector3 vector3 = tempVectorBonePos.set(hitInfo.x, hitInfo.y, hitInfo.z);
            return !isoGameCharacter.IsAttackRange(handWeapon, hitInfo.getObject(), vector3, _boolean);
        } else {
            return true;
        }
    }

    private void removeUnhittableTargets(
        IsoGameCharacter isoGameCharacter, HandWeapon handWeapon, float float0, float float1, boolean _boolean, ArrayList<HitInfo> arrayList
    ) {
        for (int _int = arrayList.size() - 1; _int >= 0; _int--) {
            HitInfo hitInfo = (HitInfo)arrayList.get(_int);
            if (this.isUnhittableTarget(isoGameCharacter, handWeapon, float0, float1, hitInfo, _boolean)) {
                this.hitInfoPool.release(hitInfo);
                arrayList.remove(_int);
            }
        }
    }

    private boolean getNearestTargetPosAndDot(
        IsoGameCharacter isoGameCharacter0, HandWeapon handWeapon, IsoMovingObject isoMovingObject, boolean _boolean, Vector4f vector4f
    ) {
        this.getNearestTargetPosAndDot(isoGameCharacter0, isoMovingObject, vector4f);
        float float0 = vector4f.w;
        float float1 = handWeapon.getMinAngle();
        float float2 = handWeapon.getMaxAngle();
        IsoGameCharacter isoGameCharacter1 = Type.tryCastTo(isoMovingObject, IsoGameCharacter.class);
        if (isoGameCharacter1 != null) {
            if (isStanding(isoMovingObject)) {
                if (handWeapon.isRanged()) {
                    float1 -= handWeapon.getAimingPerkMinAngleModifier() * ((float)isoGameCharacter0.getPerkLevel(PerkFactory.Perks.Aiming) / 2.0F);
                }
            } else {
                float1 /= 1.5F;
            }
        }

        if (!(float0 < float1) && !(float0 > float2)) {
            Vector3 vector3 = tempVectorBonePos.set(vector4f.x, vector4f.y, vector4f.z);
            return isoGameCharacter0.IsAttackRange(handWeapon, isoMovingObject, vector3, _boolean);
        } else {
            return false;
        }
    }

    private void getNearestTargetPosAndDot(IsoGameCharacter isoGameCharacter, Vector3 vector3, Vector2 vector2, Vector4f vector4f) {
        float float0 = isoGameCharacter.getDotWithForwardDirection(vector3);
        float0 = PZMath.clamp(float0, -1.0F, 1.0F);
        vector4f.w = Math.max(float0, vector4f.w);
        float float1 = IsoUtils.DistanceToSquared(
            isoGameCharacter.x, isoGameCharacter.y, (float)((int)isoGameCharacter.z * 3), vector3.x, vector3.y, (float)((int)Math.max(vector3.z, 0.0F) * 3)
        );
        if (float1 < vector2.x) {
            vector2.x = float1;
            vector4f.set(vector3.x, vector3.y, vector3.z, vector4f.w);
        }
    }

    private void getNearestTargetPosAndDot(
        IsoGameCharacter isoGameCharacter, IsoMovingObject isoMovingObject, String string, Vector2 vector2, Vector4f vector4f
    ) {
        Vector3 vector3 = getBoneWorldPos(isoMovingObject, string, tempVectorBonePos);
        this.getNearestTargetPosAndDot(isoGameCharacter, vector3, vector2, vector4f);
    }

    private void getNearestTargetPosAndDot(IsoGameCharacter isoGameCharacter1, IsoMovingObject isoMovingObject, Vector4f vector4f) {
        Vector2 vector2 = tempVector2_1.set(Float.MAX_VALUE, Float.NaN);
        vector4f.w = Float.NEGATIVE_INFINITY;
        IsoGameCharacter isoGameCharacter0 = Type.tryCastTo(isoMovingObject, IsoGameCharacter.class);
        if (isoGameCharacter0 == null) {
            this.getNearestTargetPosAndDot(isoGameCharacter1, isoMovingObject, (String)null, vector2, vector4f);
        } else {
            getBoneWorldPos(isoMovingObject, "Bip01_Head", tempVector3_1);
            getBoneWorldPos(isoMovingObject, "Bip01_HeadNub", tempVector3_2);
            tempVector3_1.addToThis(tempVector3_2);
            tempVector3_1.div(2.0F);
            Vector3 vector30 = tempVector3_1;
            if (isStanding(isoMovingObject)) {
                this.getNearestTargetPosAndDot(isoGameCharacter1, vector30, vector2, vector4f);
                this.getNearestTargetPosAndDot(isoGameCharacter1, isoMovingObject, "Bip01_Pelvis", vector2, vector4f);
                Vector3 vector31 = tempVectorBonePos.set(isoMovingObject.getX(), isoMovingObject.getY(), isoMovingObject.getZ());
                this.getNearestTargetPosAndDot(isoGameCharacter1, vector31, vector2, vector4f);
            } else {
                this.getNearestTargetPosAndDot(isoGameCharacter1, vector30, vector2, vector4f);
                this.getNearestTargetPosAndDot(isoGameCharacter1, isoMovingObject, "Bip01_Pelvis", vector2, vector4f);
                this.getNearestTargetPosAndDot(isoGameCharacter1, isoMovingObject, "Bip01_DressFrontNub", vector2, vector4f);
            }
        }
    }

    private HitInfo calcValidTarget(IsoLivingCharacter isoLivingCharacter, HandWeapon handWeapon, IsoMovingObject isoMovingObject, float float3) {
        if (isoMovingObject == isoLivingCharacter) {
            return null;
        } else {
            IsoGameCharacter isoGameCharacter = Type.tryCastTo(isoMovingObject, IsoGameCharacter.class);
            if (isoGameCharacter == null) {
                return null;
            } else if (isoGameCharacter.isGodMod()) {
                return null;
            } else if (!checkPVP(isoLivingCharacter, isoMovingObject)) {
                return null;
            } else {
                float float0 = Math.abs(isoGameCharacter.getZ() - isoLivingCharacter.getZ());
                if (!handWeapon.isRanged() && float0 >= 0.5F) {
                    return null;
                } else if (float0 > 3.3F) {
                    return null;
                } else if (!isoGameCharacter.isShootable()) {
                    return null;
                } else if (isoGameCharacter.isCurrentState(FakeDeadZombieState.instance())) {
                    return null;
                } else if (isoGameCharacter.isDead()) {
                    return null;
                } else if (isoGameCharacter.getHitReaction() != null && isoGameCharacter.getHitReaction().contains("Death")) {
                    return null;
                } else {
                    Vector4f vector4f = this.tempVector4f;
                    this.getNearestTargetPosAndDot(isoLivingCharacter, isoGameCharacter, vector4f);
                    float float1 = vector4f.w;
                    float float2 = IsoUtils.DistanceToSquared(
                        isoLivingCharacter.x,
                        isoLivingCharacter.y,
                        (float)((int)isoLivingCharacter.z * 3),
                        vector4f.x,
                        vector4f.y,
                        (float)((int)vector4f.z * 3)
                    );
                    if (float1 < 0.0F) {
                        return null;
                    } else if (float2 > float3 * float3) {
                        return null;
                    } else {
                        LosUtil.TestResults testResults = LosUtil.lineClear(
                            isoLivingCharacter.getCell(),
                            (int)isoLivingCharacter.getX(),
                            (int)isoLivingCharacter.getY(),
                            (int)isoLivingCharacter.getZ(),
                            (int)isoGameCharacter.getX(),
                            (int)isoGameCharacter.getY(),
                            (int)isoGameCharacter.getZ(),
                            false
                        );
                        return testResults != LosUtil.TestResults.Blocked && testResults != LosUtil.TestResults.ClearThroughClosedDoor
                            ? this.hitInfoPool.alloc().init(isoGameCharacter, float1, float2, vector4f.x, vector4f.y, vector4f.z)
                            : null;
                    }
                }
            }
        }
    }

    public static boolean isProne(IsoMovingObject obj) {
        IsoZombie isoZombie = Type.tryCastTo(obj, IsoZombie.class);
        if (isoZombie == null) {
            return obj.isOnFloor();
        } else if (isoZombie.isOnFloor()) {
            return true;
        } else if (isoZombie.isCurrentState(ZombieEatBodyState.instance())) {
            return true;
        } else if (isoZombie.isDead()) {
            return true;
        } else {
            return isoZombie.isSitAgainstWall() ? true : isoZombie.isCrawling();
        }
    }

    public static boolean isStanding(IsoMovingObject obj) {
        return !isProne(obj);
    }

    public boolean isProneTargetBetter(IsoGameCharacter owner, HitInfo bestStanding, HitInfo bestProne) {
        if (bestStanding == null || bestStanding.getObject() == null) {
            return false;
        } else if (bestProne == null || bestProne.getObject() == null) {
            return false;
        } else if (bestStanding.distSq <= bestProne.distSq) {
            return false;
        } else {
            int _int = (int)owner.z;
            boolean boolean0 = PolygonalMap2.instance
                .lineClearCollide(owner.x, owner.y, bestStanding.getObject().x, bestStanding.getObject().y, _int, null, false, true);
            if (!boolean0) {
                return false;
            } else {
                _int = (int)owner.z;
                boolean boolean1 = PolygonalMap2.instance
                    .lineClearCollide(owner.x, owner.y, bestProne.getObject().x, bestProne.getObject().y, _int, null, false, true);
                return !boolean1;
            }
        }
    }

    public static boolean checkPVP(IsoGameCharacter owner, IsoMovingObject obj) {
        IsoPlayer isoPlayer0 = Type.tryCastTo(owner, IsoPlayer.class);
        IsoPlayer isoPlayer1 = Type.tryCastTo(obj, IsoPlayer.class);
        if (GameClient.bClient && isoPlayer1 != null && owner != null) {
            if (isoPlayer1.isGodMod()
                || !ServerOptions.instance.PVP.getValue()
                || ServerOptions.instance.SafetySystem.getValue() && owner.getSafety().isEnabled() && ((IsoGameCharacter)obj).getSafety().isEnabled()) {
                return false;
            }

            if (NonPvpZone.getNonPvpZone((int)obj.getX(), (int)obj.getY()) != null) {
                return false;
            }

            if (isoPlayer0 != null && NonPvpZone.getNonPvpZone((int)owner.getX(), (int)owner.getY()) != null) {
                return false;
            }

            if (isoPlayer0 != null && !isoPlayer0.factionPvp && !isoPlayer1.factionPvp) {
                Faction faction0 = Faction.getPlayerFaction(isoPlayer0);
                Faction faction1 = Faction.getPlayerFaction(isoPlayer1);
                if (faction1 != null && faction0 == faction1) {
                    return false;
                }
            }
        }

        return GameClient.bClient || isoPlayer1 == null || IsoPlayer.getCoopPVP();
    }

    private void CalcHitListShove(IsoGameCharacter isoGameCharacter0, boolean boolean1, AttackVars attackVars, ArrayList<HitInfo> arrayList1) {
        HandWeapon handWeapon = attackVars.getWeapon((IsoLivingCharacter)isoGameCharacter0);
        ArrayList arrayList0 = IsoWorld.instance.CurrentCell.getObjectList();

        for (int _int = 0; _int < arrayList0.size(); _int++) {
            IsoMovingObject isoMovingObject = (IsoMovingObject)arrayList0.get(_int);
            if (isoMovingObject != isoGameCharacter0 && !(isoMovingObject instanceof BaseVehicle)) {
                IsoGameCharacter isoGameCharacter1 = Type.tryCastTo(isoMovingObject, IsoGameCharacter.class);
                if (isoGameCharacter1 != null && !isoGameCharacter1.isGodMod() && !isoGameCharacter1.isDead()) {
                    IsoZombie isoZombie = Type.tryCastTo(isoMovingObject, IsoZombie.class);
                    if ((isoZombie == null || !isoZombie.isCurrentState(FakeDeadZombieState.instance())) && checkPVP(isoGameCharacter0, isoMovingObject)) {
                        boolean boolean0 = isoMovingObject == attackVars.targetOnGround.getMovingObject()
                            || isoMovingObject.isShootable() && isStanding(isoMovingObject) && !attackVars.bAimAtFloor
                            || isoMovingObject.isShootable() && isProne(isoMovingObject) && attackVars.bAimAtFloor;
                        if (boolean0) {
                            Vector4f vector4f = this.tempVector4f;
                            if (this.getNearestTargetPosAndDot(isoGameCharacter0, handWeapon, isoMovingObject, boolean1, vector4f)) {
                                float float0 = vector4f.w;
                                float float1 = IsoUtils.DistanceToSquared(
                                    isoGameCharacter0.x,
                                    isoGameCharacter0.y,
                                    (float)((int)isoGameCharacter0.z * 3),
                                    vector4f.x,
                                    vector4f.y,
                                    (float)((int)vector4f.z * 3)
                                );
                                LosUtil.TestResults testResults = LosUtil.lineClear(
                                    isoGameCharacter0.getCell(),
                                    (int)isoGameCharacter0.getX(),
                                    (int)isoGameCharacter0.getY(),
                                    (int)isoGameCharacter0.getZ(),
                                    (int)isoMovingObject.getX(),
                                    (int)isoMovingObject.getY(),
                                    (int)isoMovingObject.getZ(),
                                    false
                                );
                                if (testResults != LosUtil.TestResults.Blocked
                                    && testResults != LosUtil.TestResults.ClearThroughClosedDoor
                                    && (
                                        isoMovingObject.getCurrentSquare() == null
                                            || isoGameCharacter0.getCurrentSquare() == null
                                            || isoMovingObject.getCurrentSquare() == isoGameCharacter0.getCurrentSquare()
                                            || !isoMovingObject.getCurrentSquare().isWindowBlockedTo(isoGameCharacter0.getCurrentSquare())
                                    )
                                    && isoMovingObject.getSquare().getTransparentWallTo(isoGameCharacter0.getSquare()) == null) {
                                    HitInfo hitInfo = this.hitInfoPool.alloc().init(isoMovingObject, float0, float1, vector4f.x, vector4f.y, vector4f.z);
                                    if (attackVars.targetOnGround.getMovingObject() == isoMovingObject) {
                                        arrayList1.clear();
                                        arrayList1.add(hitInfo);
                                        break;
                                    }

                                    arrayList1.add(hitInfo);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void CalcHitListWeapon(IsoGameCharacter isoGameCharacter0, boolean boolean1, AttackVars attackVars, ArrayList<HitInfo> arrayList1) {
        HandWeapon handWeapon = attackVars.getWeapon((IsoLivingCharacter)isoGameCharacter0);
        ArrayList arrayList0 = IsoWorld.instance.CurrentCell.getObjectList();

        for (int _int = 0; _int < arrayList0.size(); _int++) {
            IsoMovingObject isoMovingObject = (IsoMovingObject)arrayList0.get(_int);
            if (isoMovingObject != isoGameCharacter0) {
                IsoGameCharacter isoGameCharacter1 = Type.tryCastTo(isoMovingObject, IsoGameCharacter.class);
                if ((isoGameCharacter1 == null || !isoGameCharacter1.isGodMod()) && (isoGameCharacter1 == null || !isoGameCharacter1.isDead())) {
                    IsoZombie isoZombie = Type.tryCastTo(isoMovingObject, IsoZombie.class);
                    if ((isoZombie == null || !isoZombie.isCurrentState(FakeDeadZombieState.instance())) && checkPVP(isoGameCharacter0, isoMovingObject)) {
                        boolean boolean0 = isoMovingObject == attackVars.targetOnGround.getMovingObject()
                            || isoMovingObject.isShootable() && isStanding(isoMovingObject) && !attackVars.bAimAtFloor
                            || isoMovingObject.isShootable() && isProne(isoMovingObject) && attackVars.bAimAtFloor;
                        if (boolean0) {
                            Vector4f vector4f = this.tempVector4f;
                            if (isoMovingObject instanceof BaseVehicle) {
                                VehiclePart vehiclePart = ((BaseVehicle)isoMovingObject).getNearestBodyworkPart(isoGameCharacter0);
                                if (vehiclePart == null) {
                                    continue;
                                }

                                float float0 = isoGameCharacter0.getDotWithForwardDirection(isoMovingObject.x, isoMovingObject.y);
                                if (float0 < 0.8F) {
                                    continue;
                                }

                                vector4f.set(isoMovingObject.x, isoMovingObject.y, isoMovingObject.z, float0);
                            } else if (isoGameCharacter1 == null
                                || !this.getNearestTargetPosAndDot(isoGameCharacter0, handWeapon, isoMovingObject, boolean1, vector4f)) {
                                continue;
                            }

                            LosUtil.TestResults testResults = LosUtil.lineClear(
                                isoGameCharacter0.getCell(),
                                (int)isoGameCharacter0.getX(),
                                (int)isoGameCharacter0.getY(),
                                (int)isoGameCharacter0.getZ(),
                                (int)isoMovingObject.getX(),
                                (int)isoMovingObject.getY(),
                                (int)isoMovingObject.getZ(),
                                false
                            );
                            if (testResults != LosUtil.TestResults.Blocked && testResults != LosUtil.TestResults.ClearThroughClosedDoor) {
                                float float1 = vector4f.w;
                                float float2 = IsoUtils.DistanceToSquared(
                                    isoGameCharacter0.x,
                                    isoGameCharacter0.y,
                                    (float)((int)isoGameCharacter0.z * 3),
                                    vector4f.x,
                                    vector4f.y,
                                    (float)((int)vector4f.z * 3)
                                );
                                if (isoMovingObject.getSquare().getTransparentWallTo(isoGameCharacter0.getSquare()) != null
                                    && isoGameCharacter0 instanceof IsoPlayer) {
                                    if (WeaponType.getWeaponType(isoGameCharacter0) == WeaponType.spear) {
                                        ((IsoPlayer)isoGameCharacter0).setAttackType("spearStab");
                                    } else if (WeaponType.getWeaponType(isoGameCharacter0) != WeaponType.knife) {
                                        continue;
                                    }
                                }

                                IsoWindow isoWindow = this.getWindowBetween(isoGameCharacter0, isoMovingObject);
                                if (isoWindow == null || !isoWindow.isBarricaded()) {
                                    HitInfo hitInfo = this.hitInfoPool.alloc().init(isoMovingObject, float1, float2, vector4f.x, vector4f.y, vector4f.z);
                                    hitInfo.window.setObject(isoWindow);
                                    arrayList1.add(hitInfo);
                                }
                            }
                        }
                    }
                }
            }
        }

        if (arrayList1.isEmpty()) {
            this.CalcHitListWindow(isoGameCharacter0, handWeapon, arrayList1);
        }
    }

    private void CalcHitListWindow(IsoGameCharacter isoGameCharacter, HandWeapon handWeapon, ArrayList<HitInfo> arrayList1) {
        Vector2 vector2 = isoGameCharacter.getLookVector(tempVector2_1);
        vector2.setLength(handWeapon.getMaxRange() * handWeapon.getRangeMod(isoGameCharacter));
        HitInfo hitInfo = null;
        ArrayList arrayList0 = IsoWorld.instance.CurrentCell.getWindowList();

        for (int _int = 0; _int < arrayList0.size(); _int++) {
            IsoWindow isoWindow = (IsoWindow)arrayList0.get(_int);
            if ((int)isoWindow.getZ() == (int)isoGameCharacter.z && this.windowVisitor.isHittable(isoWindow)) {
                float float0 = isoWindow.getX();
                float float1 = isoWindow.getY();
                float float2 = float0 + (isoWindow.getNorth() ? 1.0F : 0.0F);
                float float3 = float1 + (isoWindow.getNorth() ? 0.0F : 1.0F);
                if (Line2D.linesIntersect(
                    (double)isoGameCharacter.x,
                    (double)isoGameCharacter.y,
                    (double)(isoGameCharacter.x + vector2.x),
                    (double)(isoGameCharacter.y + vector2.y),
                    (double)float0,
                    (double)float1,
                    (double)float2,
                    (double)float3
                )) {
                    IsoGridSquare isoGridSquare = isoWindow.getAddSheetSquare(isoGameCharacter);
                    if (isoGridSquare != null
                        && !LosUtil.lineClearCollide(
                            (int)isoGameCharacter.x, (int)isoGameCharacter.y, (int)isoGameCharacter.z, isoGridSquare.x, isoGridSquare.y, isoGridSquare.z, false
                        )) {
                        float float4 = IsoUtils.DistanceToSquared(
                            isoGameCharacter.x, isoGameCharacter.y, float0 + (float2 - float0) / 2.0F, float1 + (float3 - float1) / 2.0F
                        );
                        if (hitInfo == null || !(hitInfo.distSq < float4)) {
                            float float5 = 1.0F;
                            if (hitInfo == null) {
                                hitInfo = this.hitInfoPool.alloc();
                            }

                            hitInfo.init(isoWindow, float5, float4);
                        }
                    }
                }
            }
        }

        if (hitInfo != null) {
            arrayList1.add(hitInfo);
        }
    }

    public void CalcHitList(IsoGameCharacter owner, boolean extraRange, AttackVars attackVars, ArrayList<HitInfo> hitList) {
        if (!GameClient.bClient || owner.isLocal()) {
            this.hitInfoPool.release(hitList);
            hitList.clear();
            HandWeapon handWeapon = attackVars.getWeapon((IsoLivingCharacter)owner);
            int int0 = handWeapon.getMaxHitCount();
            if (attackVars.bDoShove) {
                int0 = WeaponType.getWeaponType(owner) != WeaponType.barehand ? 3 : 1;
            }

            if (!handWeapon.isRanged() && !zombie.SandboxOptions.instance.MultiHitZombies.getValue()) {
                int0 = 1;
            }

            if (handWeapon == ((IsoPlayer)owner).bareHands && !(owner.getPrimaryHandItem() instanceof HandWeapon)) {
                int0 = 1;
            }

            if (handWeapon == ((IsoPlayer)owner).bareHands && attackVars.targetOnGround.getMovingObject() != null) {
                int0 = 1;
            }

            if (0 < int0) {
                if (attackVars.bDoShove) {
                    this.CalcHitListShove(owner, extraRange, attackVars, hitList);
                } else {
                    this.CalcHitListWeapon(owner, extraRange, attackVars, hitList);
                }

                if (hitList.size() == 1 && ((HitInfo)hitList.get(0)).getObject() == null) {
                    return;
                }

                this.filterTargetsByZ(owner);
                Collections.sort(hitList, Comparator);
                if (handWeapon.isPiercingBullets()) {
                    HitList2.clear();
                    double double0 = 0.0;

                    for (int int1 = 0; int1 < hitList.size(); int1++) {
                        HitInfo hitInfo0 = (HitInfo)hitList.get(int1);
                        IsoMovingObject isoMovingObject = hitInfo0.getObject();
                        if (isoMovingObject != null) {
                            double double1 = (double)(owner.getX() - isoMovingObject.getX());
                            double double2 = (double)(-(owner.getY() - isoMovingObject.getY()));
                            double double3 = Math.atan2(double2, double1);
                            if (double3 < 0.0) {
                                double3 = Math.abs(double3);
                            } else {
                                double3 = (Math.PI * 2) - double3;
                            }

                            if (int1 == 0) {
                                double0 = Math.toDegrees(double3);
                                HitList2.add(hitInfo0);
                            } else {
                                double double4 = Math.toDegrees(double3);
                                if (Math.abs(double0 - double4) < 1.0) {
                                    HitList2.add(hitInfo0);
                                    break;
                                }
                            }
                        }
                    }

                    hitList.removeAll(HitList2);
                    this.hitInfoPool.release(hitList);
                    hitList.clear();
                    hitList.addAll(HitList2);
                } else {
                    while (hitList.size() > int0) {
                        this.hitInfoPool.release((HitInfo)hitList.remove(hitList.size() - 1));
                    }
                }
            }

            for (int int2 = 0; int2 < hitList.size(); int2++) {
                HitInfo hitInfo1 = (HitInfo)hitList.get(int2);
                hitInfo1.chance = this.CalcHitChance(owner, handWeapon, hitInfo1);
            }
        }
    }

    private void filterTargetsByZ(IsoGameCharacter isoGameCharacter) {
        float float0 = Float.MAX_VALUE;
        HitInfo hitInfo0 = null;

        for (int int0 = 0; int0 < isoGameCharacter.hitList.size(); int0++) {
            HitInfo hitInfo1 = (HitInfo)isoGameCharacter.hitList.get(int0);
            float float1 = Math.abs(hitInfo1.z - isoGameCharacter.getZ());
            if (float1 < float0) {
                float0 = float1;
                hitInfo0 = hitInfo1;
            }
        }

        if (hitInfo0 != null) {
            for (int int1 = isoGameCharacter.hitList.size() - 1; int1 >= 0; int1--) {
                HitInfo hitInfo2 = (HitInfo)isoGameCharacter.hitList.get(int1);
                if (hitInfo2 != hitInfo0) {
                    float float2 = Math.abs(hitInfo2.z - hitInfo0.z);
                    if (float2 > 0.5F) {
                        this.hitInfoPool.release(hitInfo2);
                        isoGameCharacter.hitList.remove(int1);
                    }
                }
            }
        }
    }

    public int CalcHitChance(IsoGameCharacter owner, HandWeapon weapon, HitInfo hitInfo) {
        IsoMovingObject isoMovingObject = hitInfo.getObject();
        if (isoMovingObject == null) {
            return 0;
        } else {
            if (owner.getVehicle() != null) {
                BaseVehicle baseVehicle = owner.getVehicle();
                Vector3f vector3f = baseVehicle.getForwardVector(((BaseVehicle.Vector3fObjectPool)BaseVehicle.TL_vector3f_pool.get()).alloc());
                Vector2 vector20 = ((BaseVehicle.Vector2ObjectPool)BaseVehicle.TL_vector2_pool.get()).alloc();
                vector20.x = vector3f.x;
                vector20.y = vector3f.z;
                vector20.normalize();
                int int0 = baseVehicle.getSeat(owner);
                VehicleScript.Area area = baseVehicle.getScript().getAreaById(baseVehicle.getPassengerArea(int0));
                byte _byte = -90;
                if (area.x > 0.0F) {
                    _byte = 90;
                }

                vector20.rotate((float)Math.toRadians((double)_byte));
                vector20.normalize();
                Vector2 vector21 = ((BaseVehicle.Vector2ObjectPool)BaseVehicle.TL_vector2_pool.get()).alloc();
                vector21.x = isoMovingObject.x;
                vector21.y = isoMovingObject.y;
                vector21.x = vector21.x - owner.x;
                vector21.y = vector21.y - owner.y;
                vector21.normalize();
                float float0 = vector21.dot(vector20);
                if ((double)float0 > -0.6) {
                    return 0;
                }

                ((BaseVehicle.Vector2ObjectPool)BaseVehicle.TL_vector2_pool.get()).release(vector20);
                ((BaseVehicle.Vector2ObjectPool)BaseVehicle.TL_vector2_pool.get()).release(vector21);
                ((BaseVehicle.Vector3fObjectPool)BaseVehicle.TL_vector3f_pool.get()).release(vector3f);
            }

            if (System.currentTimeMillis() - owner.lastAutomaticShoot > 600L) {
                owner.shootInARow = 0;
            }

            int int1 = weapon.getHitChance();
            int1 = (int)((float)int1 + weapon.getAimingPerkHitChanceModifier() * (float)owner.getPerkLevel(PerkFactory.Perks.Aiming));
            if (int1 > 95) {
                int1 = 95;
            }

            int1 -= owner.shootInARow * 2;
            float float1 = PZMath.sqrt(hitInfo.distSq);
            float float2 = 1.3F;
            if (isoMovingObject instanceof IsoPlayer) {
                float1 = (float)((double)float1 * 1.5);
                float2 = 1.0F;
            }

            int1 = (int)((float)int1 + (weapon.getMaxRange() * weapon.getRangeMod(owner) - float1) * float2);
            if (weapon.getMinRangeRanged() > 0.0F) {
                if (float1 < weapon.getMinRangeRanged()) {
                    int1 -= 50;
                }
            } else if ((double)float1 < 1.7 && weapon.isRanged() && !(isoMovingObject instanceof IsoPlayer)) {
                int1 += 35;
            }

            if (weapon.isRanged() && owner.getBeenMovingFor() > (float)(weapon.getAimingTime() + owner.getPerkLevel(PerkFactory.Perks.Aiming))) {
                int1 = (int)((float)int1 - (owner.getBeenMovingFor() - (float)(weapon.getAimingTime() + owner.getPerkLevel(PerkFactory.Perks.Aiming))));
            }

            if (hitInfo.getObject() instanceof IsoPlayer) {
                IsoPlayer isoPlayer = (IsoPlayer)hitInfo.getObject();
                if (isoPlayer.isPlayerMoving()) {
                    int1 -= 5;
                }

                if (isoPlayer.isRunning()) {
                    int1 -= 10;
                }

                if (isoPlayer.isSprinting()) {
                    int1 -= 15;
                }
            }

            if (weapon.isRanged() && owner.getVehicle() != null) {
                int1 = (int)((float)int1 - Math.abs(owner.getVehicle().getCurrentSpeedKmHour()) * 2.0F);
            }

            if (owner.Traits.Marksman.isSet()) {
                int1 += 20;
            }

            float float3 = 0.0F;

            for (int int2 = BodyPartType.ToIndex(BodyPartType.Hand_L); int2 <= BodyPartType.ToIndex(BodyPartType.UpperArm_R); int2++) {
                float3 += ((BodyPart)owner.getBodyDamage().getBodyParts().get(int2)).getPain();
            }

            if (float3 > 0.0F) {
                int1 = (int)((float)int1 - float3 / 10.0F);
            }

            int1 -= owner.getMoodles().getMoodleLevel(MoodleType.Tired) * 5;
            if (int1 <= 10) {
                int1 = 10;
            }

            if (int1 > 100 || !weapon.isRanged()) {
                int1 = 100;
            }

            return int1;
        }
    }

    public static Vector3 getBoneWorldPos(IsoMovingObject target, String boneName, Vector3 bonePos) {
        IsoGameCharacter isoGameCharacter = Type.tryCastTo(target, IsoGameCharacter.class);
        if (isoGameCharacter != null && boneName != null) {
            AnimationPlayer animationPlayer = isoGameCharacter.getAnimationPlayer();
            if (animationPlayer != null && animationPlayer.isReady()) {
                int _int = animationPlayer.getSkinningBoneIndex(boneName, -1);
                if (_int == -1) {
                    return bonePos.set(target.x, target.y, target.z);
                } else {
                    Model.BoneToWorldCoords(isoGameCharacter, _int, bonePos);
                    return bonePos;
                }
            } else {
                return bonePos.set(target.x, target.y, target.z);
            }
        } else {
            return bonePos.set(target.x, target.y, target.z);
        }
    }

    public void ConnectSwing(IsoGameCharacter owner, HandWeapon weapon) {
        HashMap hashMap = owner.getStateMachineParams(this);
        IsoLivingCharacter isoLivingCharacter = (IsoLivingCharacter)owner;
        IsoPlayer isoPlayer = Type.tryCastTo(owner, IsoPlayer.class);
        if (owner.getVariableBoolean("ShoveAnim")) {
            isoLivingCharacter.setDoShove(true);
        }

        if (GameServer.bServer) {
            DebugLog.log(DebugType.Network, "Player swing connects.");
        }

        LuaEventManager.triggerEvent("OnWeaponSwingHitPoint", owner, weapon);
        if (weapon.getPhysicsObject() != null) {
            owner.Throw(weapon);
        }

        if (weapon.isUseSelf()) {
            weapon.Use();
        }

        if (weapon.isOtherHandUse() && owner.getSecondaryHandItem() != null) {
            owner.getSecondaryHandItem().Use();
        }

        boolean boolean0 = false;
        if (isoLivingCharacter.bDoShove && !owner.isAimAtFloor()) {
            boolean0 = true;
        }

        boolean boolean1 = false;
        boolean boolean2 = false;
        owner.attackVars.setWeapon(weapon);
        owner.attackVars.targetOnGround.setMovingObject(isoLivingCharacter.targetOnGround);
        owner.attackVars.bAimAtFloor = owner.isAimAtFloor();
        owner.attackVars.bDoShove = isoLivingCharacter.bDoShove;
        if (owner.getVariableBoolean("ShoveAnim")) {
            owner.attackVars.bDoShove = true;
        }

        this.CalcHitList(owner, false, owner.attackVars, owner.hitList);
        int int0 = owner.hitList.size();
        boolean boolean3 = false;
        if (int0 == 0) {
            boolean3 = this.CheckObjectHit(owner, weapon);
        }

        if (weapon.isUseEndurance()) {
            float float0 = 0.0F;
            if (weapon.isTwoHandWeapon() && (owner.getPrimaryHandItem() != weapon || owner.getSecondaryHandItem() != weapon)) {
                float0 = weapon.getWeight() / 1.5F / 10.0F;
            }

            if (int0 <= 0 && !owner.isForceShove()) {
                float float1 = (weapon.getWeight() * 0.18F * weapon.getFatigueMod(owner) * owner.getFatigueMod() * weapon.getEnduranceMod() * 0.3F + float0)
                    * 0.04F;
                float float2 = 1.0F;
                if (owner.Traits.Asthmatic.isSet()) {
                    float2 = 1.3F;
                }

                owner.getStats().endurance -= float1 * float2;
            }
        }

        owner.setLastHitCount(owner.hitList.size());
        if (!weapon.isMultipleHitConditionAffected()) {
            boolean1 = true;
        }

        int int1 = 1;
        this.dotList.clear();
        if (owner.hitList.isEmpty() && owner.getClickSound() != null && !isoLivingCharacter.bDoShove) {
            if (owner instanceof IsoPlayer && ((IsoPlayer)owner).isLocalPlayer() || !(owner instanceof IsoPlayer)) {
                owner.getEmitter().playSound(owner.getClickSound());
            }

            owner.setRecoilDelay(10.0F);
        }

        boolean boolean4 = false;

        for (int int2 = 0; int2 < owner.hitList.size(); int2++) {
            byte byte0 = 0;
            boolean boolean5 = false;
            HitInfo hitInfo = (HitInfo)owner.hitList.get(int2);
            IsoMovingObject isoMovingObject = hitInfo.getObject();
            BaseVehicle baseVehicle = Type.tryCastTo(isoMovingObject, BaseVehicle.class);
            IsoZombie isoZombie = Type.tryCastTo(isoMovingObject, IsoZombie.class);
            if (hitInfo.getObject() == null && hitInfo.window.getObject() != null) {
                hitInfo.window.getObject().WeaponHit(owner, weapon);
            } else {
                this.smashWindowBetween(owner, isoMovingObject, weapon);
                if (!this.isWindowBetween(owner, isoMovingObject)) {
                    int int3 = hitInfo.chance;
                    boolean boolean6 = Rand.Next(100) <= int3;
                    if (boolean6) {
                        Vector2 vector20 = tempVector2_1.set(owner.getX(), owner.getY());
                        Vector2 vector21 = tempVector2_2.set(isoMovingObject.getX(), isoMovingObject.getY());
                        vector21.x = vector21.x - vector20.x;
                        vector21.y = vector21.y - vector20.y;
                        Vector2 vector22 = owner.getLookVector(tempVector2_1);
                        vector22.tangent();
                        vector21.normalize();
                        boolean boolean7 = true;
                        float float3 = vector22.dot(vector21);

                        for (int int4 = 0; int4 < this.dotList.size(); int4++) {
                            float float4 = (Float)this.dotList.get(int4);
                            if ((double)Math.abs(float3 - float4) < 1.0E-4) {
                                boolean7 = false;
                            }
                        }

                        float float5 = weapon.getMinDamage();
                        float float6 = weapon.getMaxDamage();
                        long _long = 0L;
                        if (!boolean7) {
                            float5 /= 5.0F;
                            float6 /= 5.0F;
                        }

                        if (owner.isAimAtFloor() && !weapon.isRanged() && owner.isNPC()) {
                            splash(isoMovingObject, weapon, owner);
                            byte0 = (byte)Rand.Next(2);
                        } else if (owner.isAimAtFloor() && !weapon.isRanged()) {
                            if (isoPlayer == null || isoPlayer.isLocalPlayer()) {
                                if (!StringUtils.isNullOrEmpty(weapon.getHitFloorSound())) {
                                    owner.getEmitter().stopSoundByName(weapon.getSwingSound());
                                    if (isoPlayer != null) {
                                        isoPlayer.setMeleeHitSurface(ParameterMeleeHitSurface.Material.Body);
                                    }

                                    _long = owner.playSound(weapon.getHitFloorSound());
                                } else {
                                    owner.getEmitter().stopSoundByName(weapon.getSwingSound());
                                    if (isoPlayer != null) {
                                        isoPlayer.setMeleeHitSurface(ParameterMeleeHitSurface.Material.Body);
                                    }

                                    _long = owner.playSound(weapon.getZombieHitSound());
                                }
                            }

                            int int5 = this.DoSwingCollisionBoneCheck(
                                owner,
                                GetWeapon(owner),
                                (IsoGameCharacter)isoMovingObject,
                                ((IsoGameCharacter)isoMovingObject).getAnimationPlayer().getSkinningBoneIndex("Bip01_Head", -1),
                                0.28F
                            );
                            if (int5 == -1) {
                                int5 = this.DoSwingCollisionBoneCheck(
                                    owner,
                                    GetWeapon(owner),
                                    (IsoGameCharacter)isoMovingObject,
                                    ((IsoGameCharacter)isoMovingObject).getAnimationPlayer().getSkinningBoneIndex("Bip01_Spine", -1),
                                    0.28F
                                );
                                if (int5 == -1) {
                                    int5 = this.DoSwingCollisionBoneCheck(
                                        owner,
                                        GetWeapon(owner),
                                        (IsoGameCharacter)isoMovingObject,
                                        ((IsoGameCharacter)isoMovingObject).getAnimationPlayer().getSkinningBoneIndex("Bip01_L_Calf", -1),
                                        0.13F
                                    );
                                    if (int5 == -1) {
                                        int5 = this.DoSwingCollisionBoneCheck(
                                            owner,
                                            GetWeapon(owner),
                                            (IsoGameCharacter)isoMovingObject,
                                            ((IsoGameCharacter)isoMovingObject).getAnimationPlayer().getSkinningBoneIndex("Bip01_R_Calf", -1),
                                            0.13F
                                        );
                                    }

                                    if (int5 == -1) {
                                        int5 = this.DoSwingCollisionBoneCheck(
                                            owner,
                                            GetWeapon(owner),
                                            (IsoGameCharacter)isoMovingObject,
                                            ((IsoGameCharacter)isoMovingObject).getAnimationPlayer().getSkinningBoneIndex("Bip01_L_Foot", -1),
                                            0.23F
                                        );
                                    }

                                    if (int5 == -1) {
                                        int5 = this.DoSwingCollisionBoneCheck(
                                            owner,
                                            GetWeapon(owner),
                                            (IsoGameCharacter)isoMovingObject,
                                            ((IsoGameCharacter)isoMovingObject).getAnimationPlayer().getSkinningBoneIndex("Bip01_R_Foot", -1),
                                            0.23F
                                        );
                                    }

                                    if (int5 == -1) {
                                        continue;
                                    }

                                    boolean5 = true;
                                }
                            } else {
                                splash(isoMovingObject, weapon, owner);
                                splash(isoMovingObject, weapon, owner);
                                byte0 = (byte)(Rand.Next(0, 3) + 1);
                            }
                        }

                        if (!owner.attackVars.bAimAtFloor
                            && (!owner.attackVars.bCloseKill || !owner.isCriticalHit())
                            && !isoLivingCharacter.bDoShove
                            && isoMovingObject instanceof IsoGameCharacter
                            && (isoPlayer == null || isoPlayer.isLocalPlayer())) {
                            if (isoPlayer != null) {
                                isoPlayer.setMeleeHitSurface(ParameterMeleeHitSurface.Material.Body);
                            }

                            if (weapon.isRanged()) {
                                _long = ((IsoGameCharacter)isoMovingObject).playSound(weapon.getZombieHitSound());
                            } else {
                                owner.getEmitter().stopSoundByName(weapon.getSwingSound());
                                _long = owner.playSound(weapon.getZombieHitSound());
                            }
                        }

                        if (weapon.isRanged() && isoZombie != null) {
                            Vector2 vector23 = tempVector2_1.set(owner.getX(), owner.getY());
                            Vector2 vector24 = tempVector2_2.set(isoMovingObject.getX(), isoMovingObject.getY());
                            vector24.x = vector24.x - vector23.x;
                            vector24.y = vector24.y - vector23.y;
                            Vector2 vector25 = isoZombie.getForwardDirection();
                            vector24.normalize();
                            vector25.normalize();
                            float float7 = vector24.dot(vector25);
                            isoZombie.setHitFromBehind((double)float7 > 0.5);
                        }

                        if (this.dotList.isEmpty()) {
                            this.dotList.add(float3);
                        }

                        if (isoZombie != null && isoZombie.isCurrentState(ZombieOnGroundState.instance())) {
                            isoZombie.setReanimateTimer(isoZombie.getReanimateTimer() + (float)Rand.Next(10));
                        }

                        if (isoZombie != null && isoZombie.isCurrentState(ZombieGetUpState.instance())) {
                            isoZombie.setReanimateTimer((float)(Rand.Next(60) + 30));
                        }

                        boolean boolean8 = false;
                        if (!weapon.isTwoHandWeapon() || owner.isItemInBothHands(weapon)) {
                            boolean8 = true;
                        }

                        float float8 = float6 - float5;
                        float float9;
                        if (float8 == 0.0F) {
                            float9 = float5 + 0.0F;
                        } else {
                            float9 = float5 + (float)Rand.Next((int)(float8 * 1000.0F)) / 1000.0F;
                        }

                        if (!weapon.isRanged()) {
                            float9 *= weapon.getDamageMod(owner) * owner.getHittingMod();
                        }

                        if (!boolean8 && !weapon.isRanged() && float6 > float5) {
                            float9 -= float5;
                        }

                        if (owner.isAimAtFloor() && isoLivingCharacter.bDoShove) {
                            float float10 = 0.0F;

                            for (int int6 = BodyPartType.ToIndex(BodyPartType.UpperLeg_L); int6 <= BodyPartType.ToIndex(BodyPartType.Foot_R); int6++) {
                                float10 += ((BodyPart)owner.getBodyDamage().getBodyParts().get(int6)).getPain();
                            }

                            if (float10 > 10.0F) {
                                float9 /= PZMath.clamp(float10 / 10.0F, 1.0F, 30.0F);
                                MoodlesUI.getInstance().wiggle(MoodleType.Pain);
                                MoodlesUI.getInstance().wiggle(MoodleType.Injured);
                            }
                        } else {
                            float float11 = 0.0F;

                            for (int int7 = BodyPartType.ToIndex(BodyPartType.Hand_L); int7 <= BodyPartType.ToIndex(BodyPartType.UpperArm_R); int7++) {
                                float11 += ((BodyPart)owner.getBodyDamage().getBodyParts().get(int7)).getPain();
                            }

                            if (float11 > 10.0F) {
                                float9 /= PZMath.clamp(float11 / 10.0F, 1.0F, 30.0F);
                                MoodlesUI.getInstance().wiggle(MoodleType.Pain);
                                MoodlesUI.getInstance().wiggle(MoodleType.Injured);
                            }
                        }

                        if (owner.Traits.Underweight.isSet()) {
                            float9 *= 0.8F;
                        }

                        if (owner.Traits.VeryUnderweight.isSet()) {
                            float9 *= 0.6F;
                        }

                        if (owner.Traits.Emaciated.isSet()) {
                            float9 *= 0.4F;
                        }

                        float float12 = float9 / ((float)int1 / 2.0F);
                        if (owner.isAttackWasSuperAttack()) {
                            float12 *= 5.0F;
                        }

                        int1++;
                        if (weapon.isMultipleHitConditionAffected()) {
                            boolean1 = true;
                        }

                        Vector2 vector26 = tempVector2_1.set(owner.getX(), owner.getY());
                        Vector2 vector27 = tempVector2_2.set(isoMovingObject.getX(), isoMovingObject.getY());
                        vector27.x = vector27.x - vector26.x;
                        vector27.y = vector27.y - vector26.y;
                        float float13 = vector27.getLength();
                        float float14 = 1.0F;
                        if (weapon.isRangeFalloff()) {
                            float14 = 1.0F;
                        } else if (weapon.isRanged()) {
                            float14 = 0.5F;
                        } else {
                            float14 = float13 / weapon.getMaxRange(owner);
                        }

                        float14 *= 2.0F;
                        if (float14 < 0.3F) {
                            float14 = 1.0F;
                        }

                        if (weapon.isRanged() && owner.getPerkLevel(PerkFactory.Perks.Aiming) < 6 && owner.getMoodles().getMoodleLevel(MoodleType.Panic) > 2) {
                            float12 -= (float)owner.getMoodles().getMoodleLevel(MoodleType.Panic) * 0.2F;
                            MoodlesUI.getInstance().wiggle(MoodleType.Panic);
                        }

                        if (!weapon.isRanged() && owner.getMoodles().getMoodleLevel(MoodleType.Panic) > 1) {
                            float12 -= (float)owner.getMoodles().getMoodleLevel(MoodleType.Panic) * 0.1F;
                            MoodlesUI.getInstance().wiggle(MoodleType.Panic);
                        }

                        if (owner.getMoodles().getMoodleLevel(MoodleType.Stress) > 1) {
                            float12 -= (float)owner.getMoodles().getMoodleLevel(MoodleType.Stress) * 0.1F;
                            MoodlesUI.getInstance().wiggle(MoodleType.Stress);
                        }

                        if (float12 < 0.0F) {
                            float12 = 0.1F;
                        }

                        if (owner.isAimAtFloor() && isoLivingCharacter.bDoShove) {
                            float12 = Rand.Next(0.7F, 1.0F) + (float)owner.getPerkLevel(PerkFactory.Perks.Strength) * 0.2F;
                            Clothing clothing = (Clothing)owner.getWornItem("Shoes");
                            if (clothing == null) {
                                float12 *= 0.5F;
                            } else {
                                float12 *= clothing.getStompPower();
                            }
                        }

                        if (!weapon.isRanged()) {
                            switch (owner.getMoodles().getMoodleLevel(MoodleType.Endurance)) {
                                case 0:
                                default:
                                    break;
                                case 1:
                                    float12 *= 0.5F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Endurance);
                                    break;
                                case 2:
                                    float12 *= 0.2F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Endurance);
                                    break;
                                case 3:
                                    float12 *= 0.1F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Endurance);
                                    break;
                                case 4:
                                    float12 *= 0.05F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Endurance);
                            }

                            switch (owner.getMoodles().getMoodleLevel(MoodleType.Tired)) {
                                case 0:
                                default:
                                    break;
                                case 1:
                                    float12 *= 0.5F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Tired);
                                    break;
                                case 2:
                                    float12 *= 0.2F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Tired);
                                    break;
                                case 3:
                                    float12 *= 0.1F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Tired);
                                    break;
                                case 4:
                                    float12 *= 0.05F;
                                    MoodlesUI.getInstance().wiggle(MoodleType.Tired);
                            }
                        }

                        owner.knockbackAttackMod = 1.0F;
                        if ("KnifeDeath".equals(owner.getVariableString("ZombieHitReaction"))) {
                            float14 *= 1000.0F;
                            owner.knockbackAttackMod = 0.0F;
                            owner.addWorldSoundUnlessInvisible(4, 4, false);
                            owner.attackVars.bCloseKill = true;
                            isoMovingObject.setCloseKilled(true);
                        } else {
                            owner.attackVars.bCloseKill = false;
                            isoMovingObject.setCloseKilled(false);
                            owner.addWorldSoundUnlessInvisible(8, 8, false);
                            if (Rand.Next(3) != 0 && (!owner.isAimAtFloor() || !isoLivingCharacter.bDoShove)) {
                                if (Rand.Next(7) == 0) {
                                    owner.addWorldSoundUnlessInvisible(16, 16, false);
                                }
                            } else {
                                owner.addWorldSoundUnlessInvisible(10, 10, false);
                            }
                        }

                        isoMovingObject.setHitFromAngle(hitInfo.dot);
                        if (isoZombie != null) {
                            isoZombie.setHitFromBehind(owner.isBehind(isoZombie));
                            isoZombie.setHitAngle(owner.getForwardDirection());
                            isoZombie.setPlayerAttackPosition(isoZombie.testDotSide(owner));
                            isoZombie.setHitHeadWhileOnFloor(byte0);
                            isoZombie.setHitLegsWhileOnFloor(boolean5);
                            if (byte0 > 0) {
                                isoZombie.addBlood(BloodBodyPartType.Head, true, true, true);
                                isoZombie.addBlood(BloodBodyPartType.Torso_Upper, true, false, false);
                                isoZombie.addBlood(BloodBodyPartType.UpperArm_L, true, false, false);
                                isoZombie.addBlood(BloodBodyPartType.UpperArm_R, true, false, false);
                                float12 *= 3.0F;
                            }

                            if (boolean5) {
                                float12 = 0.05F;
                            }

                            int int8 = 0;
                            if (byte0 > 0) {
                                int8 = Rand.Next(BodyPartType.ToIndex(BodyPartType.Head), BodyPartType.ToIndex(BodyPartType.Neck) + 1);
                            } else if (boolean5) {
                                int8 = Rand.Next(BodyPartType.ToIndex(BodyPartType.Groin), BodyPartType.ToIndex(BodyPartType.Foot_R) + 1);
                            } else {
                                int8 = Rand.Next(BodyPartType.ToIndex(BodyPartType.Hand_L), BodyPartType.ToIndex(BodyPartType.Neck) + 1);
                            }

                            float float15 = isoZombie.getBodyPartClothingDefense(Integer.valueOf(int8), false, weapon.isRanged()) / 2.0F;
                            float15 += isoZombie.getBodyPartClothingDefense(Integer.valueOf(int8), true, weapon.isRanged());
                            if (float15 > 70.0F) {
                                float15 = 70.0F;
                            }

                            float float16 = float12 * Math.abs(1.0F - float15 / 100.0F);
                            float12 = float16;
                            if (!GameClient.bClient && !GameServer.bServer
                                || GameClient.bClient && owner instanceof IsoPlayer && ((IsoPlayer)owner).isLocalPlayer()) {
                                boolean2 = isoZombie.helmetFall(byte0 > 0);
                            }

                            if ("KnifeDeath".equals(owner.getVariableString("ZombieHitReaction")) && !"Tutorial".equals(Core.GameMode)) {
                                byte byte1 = 8;
                                if (isoZombie.isCurrentState(AttackState.instance())) {
                                    byte1 = 3;
                                }

                                int int9 = owner.getPerkLevel(PerkFactory.Perks.SmallBlade) + 1;
                                if (Rand.NextBool(byte1 + int9 * 2)) {
                                    InventoryItem inventoryItem = owner.getPrimaryHandItem();
                                    owner.getInventory().Remove(inventoryItem);
                                    owner.removeFromHands(inventoryItem);
                                    isoZombie.setAttachedItem("JawStab", inventoryItem);
                                    isoZombie.setJawStabAttach(true);
                                }

                                isoZombie.setKnifeDeath(true);
                            }
                        }

                        float float17 = 0.0F;
                        boolean boolean9 = owner.isCriticalHit();
                        if (baseVehicle == null && isoMovingObject.getSquare() != null && owner.getSquare() != null) {
                            isoMovingObject.setCloseKilled(owner.attackVars.bCloseKill);
                            if (((IsoPlayer)owner).isLocalPlayer() || owner.isNPC()) {
                                float17 = isoMovingObject.Hit(weapon, owner, float12, boolean0, float14);
                                this.setParameterCharacterHitResult(owner, isoZombie, _long);
                            }

                            LuaEventManager.triggerEvent("OnWeaponHitXp", owner, weapon, isoMovingObject, float12);
                            if ((!isoLivingCharacter.bDoShove || owner.isAimAtFloor())
                                && owner.DistToSquared(isoMovingObject) < 2.0F
                                && Math.abs(owner.z - isoMovingObject.z) < 0.5F) {
                                owner.addBlood(null, false, false, false);
                            }

                            if (isoMovingObject instanceof IsoGameCharacter) {
                                if (((IsoGameCharacter)isoMovingObject).isDead()) {
                                    owner.getStats().stress -= 0.02F;
                                } else if (!(isoMovingObject instanceof IsoPlayer) && (!isoLivingCharacter.bDoShove || owner.isAimAtFloor())) {
                                    splash(isoMovingObject, weapon, owner);
                                }
                            }
                        } else if (baseVehicle != null) {
                            VehiclePart vehiclePart0 = baseVehicle.getNearestBodyworkPart(owner);
                            if (vehiclePart0 != null) {
                                VehicleWindow vehicleWindow = vehiclePart0.getWindow();

                                for (int int10 = 0; int10 < vehiclePart0.getChildCount(); int10++) {
                                    VehiclePart vehiclePart1 = vehiclePart0.getChild(int10);
                                    if (vehiclePart1.getWindow() != null) {
                                        vehicleWindow = vehiclePart1.getWindow();
                                        break;
                                    }
                                }

                                if (vehicleWindow != null && vehicleWindow.isHittable()) {
                                    int int11 = this.calcDamageToVehicle((int)float12 * 10, weapon.getDoorDamage(), true);
                                    vehicleWindow.damage(int11);
                                    owner.playSound("HitVehicleWindowWithWeapon");
                                } else {
                                    int int12 = this.calcDamageToVehicle((int)float12 * 10, weapon.getDoorDamage(), false);
                                    vehiclePart0.setCondition(vehiclePart0.getCondition() - int12);
                                    isoPlayer.setVehicleHitLocation(baseVehicle);
                                    owner.playSound("HitVehiclePartWithWeapon");
                                }
                            }
                        }

                        if (GameClient.bClient && owner.isLocal()) {
                            if (isoMovingObject instanceof IsoGameCharacter) {
                                HitReactionNetworkAI.CalcHitReactionWeapon(owner, (IsoGameCharacter)isoMovingObject, weapon);
                            }

                            boolean4 = GameClient.sendHitCharacter(owner, isoMovingObject, weapon, float17, boolean0, float14, boolean9, boolean2, byte0 > 0);
                        }
                    }
                }
            }
        }

        if (GameClient.bClient && ((IsoPlayer)owner).isLocalPlayer() && !boolean4) {
            GameClient.sendHitCharacter(owner, null, weapon, 0.0F, boolean0, 1.0F, owner.isCriticalHit(), false, false);
        }

        if (!boolean1 && boolean3) {
            boolean boolean10 = this.bHitOnlyTree && weapon.getScriptItem().Categories.contains("Axe");
            int int13 = boolean10 ? 2 : 1;
            if (Rand.Next(weapon.getConditionLowerChance() * int13 + owner.getMaintenanceMod() * 2) == 0) {
                boolean1 = true;
            } else if (Rand.NextBool(2)
                && WeaponType.getWeaponType(owner) != WeaponType.barehand
                && (!weapon.isTwoHandWeapon() || owner.getPrimaryHandItem() == weapon || owner.getSecondaryHandItem() == weapon || !Rand.NextBool(3))) {
                owner.getXp().AddXP(PerkFactory.Perks.Maintenance, 1.0F);
            }
        }

        hashMap.put(PARAM_LOWER_CONDITION, boolean1 ? Boolean.TRUE : Boolean.FALSE);
        hashMap.put(PARAM_ATTACKED, Boolean.TRUE);
    }

    private int calcDamageToVehicle(int int0, int int2, boolean _boolean) {
        if (int0 <= 0) {
            return 0;
        } else {
            float float0 = (float)int0;
            float float1 = PZMath.clamp(float0 / (_boolean ? 10.0F : 40.0F), 0.0F, 1.0F);
            int int1 = (int)((float)int2 * float1);
            return PZMath.clamp(int1, 1, int2);
        }
    }

    public static void splash(IsoMovingObject obj, HandWeapon weapon, IsoGameCharacter owner) {
        IsoGameCharacter isoGameCharacter = (IsoGameCharacter)obj;
        if (weapon != null && zombie.SandboxOptions.instance.BloodLevel.getValue() > 1) {
            int int0 = weapon.getSplatNumber();
            if (int0 < 1) {
                int0 = 1;
            }

            if (Core.bLastStand) {
                int0 *= 3;
            }

            switch (zombie.SandboxOptions.instance.BloodLevel.getValue()) {
                case 2:
                    int0 /= 2;
                case 3:
                default:
                    break;
                case 4:
                    int0 *= 2;
                    break;
                case 5:
                    int0 *= 5;
            }

            for (int int1 = 0; int1 < int0; int1++) {
                isoGameCharacter.splatBlood(3, 0.3F);
            }
        }

        byte byte0 = 3;
        byte byte1 = 7;
        switch (zombie.SandboxOptions.instance.BloodLevel.getValue()) {
            case 1:
                byte1 = 0;
                break;
            case 2:
                byte1 = 4;
                byte0 = 5;
            case 3:
            default:
                break;
            case 4:
                byte1 = 10;
                byte0 = 2;
                break;
            case 5:
                byte1 = 15;
                byte0 = 0;
        }

        if (zombie.SandboxOptions.instance.BloodLevel.getValue() > 1) {
            isoGameCharacter.splatBloodFloorBig();
        }

        float float0 = 0.5F;
        if (isoGameCharacter instanceof IsoZombie
            && (((IsoZombie)isoGameCharacter).bCrawling || isoGameCharacter.getCurrentState() == ZombieOnGroundState.instance())) {
            float0 = 0.2F;
        }

        float float1 = Rand.Next(1.5F, 5.0F);
        float float2 = Rand.Next(1.5F, 5.0F);
        if (owner instanceof IsoPlayer && ((IsoPlayer)owner).bDoShove) {
            float1 = Rand.Next(0.0F, 0.5F);
            float2 = Rand.Next(0.0F, 0.5F);
        }

        if (byte1 > 0) {
            isoGameCharacter.playBloodSplatterSound();
        }

        for (int int2 = 0; int2 < byte1; int2++) {
            if (Rand.Next(byte0) == 0) {
                new IsoZombieGiblets(
                    IsoZombieGiblets.GibletType.A,
                    isoGameCharacter.getCell(),
                    isoGameCharacter.getX(),
                    isoGameCharacter.getY(),
                    isoGameCharacter.getZ() + float0,
                    isoGameCharacter.getHitDir().x * float1,
                    isoGameCharacter.getHitDir().y * float2
                );
            }
        }
    }

    private boolean checkObjectHit(IsoGameCharacter isoGameCharacter, HandWeapon handWeapon, IsoGridSquare isoGridSquare, boolean boolean1, boolean boolean0) {
        if (isoGridSquare == null) {
            return false;
        } else {
            for (int _int = isoGridSquare.getSpecialObjects().size() - 1; _int >= 0; _int--) {
                IsoObject isoObject = (IsoObject)isoGridSquare.getSpecialObjects().get(_int);
                IsoDoor isoDoor = Type.tryCastTo(isoObject, IsoDoor.class);
                IsoThumpable isoThumpable = Type.tryCastTo(isoObject, IsoThumpable.class);
                IsoWindow isoWindow = Type.tryCastTo(isoObject, IsoWindow.class);
                if (isoDoor != null && (boolean1 && isoDoor.north || boolean0 && !isoDoor.north)) {
                    Thumpable thumpable0 = isoDoor.getThumpableFor(isoGameCharacter);
                    if (thumpable0 != null) {
                        thumpable0.WeaponHit(isoGameCharacter, handWeapon);
                        return true;
                    }
                }

                if (isoThumpable != null) {
                    if (!isoThumpable.isDoor() && !isoThumpable.isWindow() && isoThumpable.isBlockAllTheSquare()) {
                        Thumpable thumpable1 = isoThumpable.getThumpableFor(isoGameCharacter);
                        if (thumpable1 != null) {
                            thumpable1.WeaponHit(isoGameCharacter, handWeapon);
                            return true;
                        }
                    } else if (boolean1 && isoThumpable.north || boolean0 && !isoThumpable.north) {
                        Thumpable thumpable2 = isoThumpable.getThumpableFor(isoGameCharacter);
                        if (thumpable2 != null) {
                            thumpable2.WeaponHit(isoGameCharacter, handWeapon);
                            return true;
                        }
                    }
                }

                if (isoWindow != null && (boolean1 && isoWindow.north || boolean0 && !isoWindow.north)) {
                    Thumpable thumpable3 = isoWindow.getThumpableFor(isoGameCharacter);
                    if (thumpable3 != null) {
                        thumpable3.WeaponHit(isoGameCharacter, handWeapon);
                        return true;
                    }
                }
            }

            return false;
        }
    }

    private boolean CheckObjectHit(IsoGameCharacter isoGameCharacter, HandWeapon handWeapon) {
        if (isoGameCharacter.isAimAtFloor()) {
            this.bHitOnlyTree = false;
            return false;
        } else {
            boolean _boolean = false;
            int int0 = 0;
            int int1 = 0;
            IsoDirections isoDirections = IsoDirections.fromAngle(isoGameCharacter.getForwardDirection());
            int int2 = 0;
            int int3 = 0;
            if (isoDirections == IsoDirections.NE || isoDirections == IsoDirections.N || isoDirections == IsoDirections.NW) {
                int3--;
            }

            if (isoDirections == IsoDirections.SE || isoDirections == IsoDirections.S || isoDirections == IsoDirections.SW) {
                int3++;
            }

            if (isoDirections == IsoDirections.NW || isoDirections == IsoDirections.W || isoDirections == IsoDirections.SW) {
                int2--;
            }

            if (isoDirections == IsoDirections.NE || isoDirections == IsoDirections.E || isoDirections == IsoDirections.SE) {
                int2++;
            }

            IsoCell isoCell = IsoWorld.instance.CurrentCell;
            IsoGridSquare isoGridSquare0 = isoGameCharacter.getCurrentSquare();
            IsoGridSquare isoGridSquare1 = isoCell.getGridSquare(isoGridSquare0.getX() + int2, isoGridSquare0.getY() + int3, isoGridSquare0.getZ());
            if (isoGridSquare1 != null) {
                if (this.checkObjectHit(isoGameCharacter, handWeapon, isoGridSquare1, false, false)) {
                    _boolean = true;
                    int0++;
                }

                if (!isoGridSquare1.isBlockedTo(isoGridSquare0)) {
                    for (int int4 = 0; int4 < isoGridSquare1.getObjects().size(); int4++) {
                        IsoObject isoObject = isoGridSquare1.getObjects().get(int4);
                        if (isoObject instanceof IsoTree) {
                            ((IsoTree)isoObject).WeaponHit(isoGameCharacter, handWeapon);
                            _boolean = true;
                            int0++;
                            int1++;
                            if (isoObject.getObjectIndex() == -1) {
                                int4--;
                            }
                        }
                    }
                }
            }

            if ((isoDirections == IsoDirections.NE || isoDirections == IsoDirections.N || isoDirections == IsoDirections.NW)
                && this.checkObjectHit(isoGameCharacter, handWeapon, isoGridSquare0, true, false)) {
                _boolean = true;
                int0++;
            }

            if (isoDirections == IsoDirections.SE || isoDirections == IsoDirections.S || isoDirections == IsoDirections.SW) {
                IsoGridSquare isoGridSquare2 = isoCell.getGridSquare(isoGridSquare0.getX(), isoGridSquare0.getY() + 1, isoGridSquare0.getZ());
                if (this.checkObjectHit(isoGameCharacter, handWeapon, isoGridSquare2, true, false)) {
                    _boolean = true;
                    int0++;
                }
            }

            if (isoDirections == IsoDirections.SE || isoDirections == IsoDirections.E || isoDirections == IsoDirections.NE) {
                IsoGridSquare isoGridSquare3 = isoCell.getGridSquare(isoGridSquare0.getX() + 1, isoGridSquare0.getY(), isoGridSquare0.getZ());
                if (this.checkObjectHit(isoGameCharacter, handWeapon, isoGridSquare3, false, true)) {
                    _boolean = true;
                    int0++;
                }
            }

            if ((isoDirections == IsoDirections.NW || isoDirections == IsoDirections.W || isoDirections == IsoDirections.SW)
                && this.checkObjectHit(isoGameCharacter, handWeapon, isoGridSquare0, false, true)) {
                _boolean = true;
                int0++;
            }

            this.bHitOnlyTree = _boolean && int0 == int1;
            return _boolean;
        }
    }

    private LosUtil.TestResults los(int int5, int int2, int int4, int int1, int int7, SwipeStatePlayer.LOSVisitor lOSVisitor) {
        IsoCell isoCell = IsoWorld.instance.CurrentCell;
        int int0 = int1 - int2;
        int int3 = int4 - int5;
        int int6 = int7 - int7;
        float float0 = 0.5F;
        float float1 = 0.5F;
        IsoGridSquare isoGridSquare0 = isoCell.getGridSquare(int5, int2, int7);
        if (Math.abs(int3) > Math.abs(int0)) {
            float float2 = (float)int0 / (float)int3;
            float float3 = (float)int6 / (float)int3;
            float0 += (float)int2;
            float1 += (float)int7;
            int3 = int3 < 0 ? -1 : 1;
            float2 *= (float)int3;
            float3 *= (float)int3;

            while (int5 != int4) {
                int5 += int3;
                float0 += float2;
                float1 += float3;
                IsoGridSquare isoGridSquare1 = isoCell.getGridSquare(int5, (int)float0, (int)float1);
                if (lOSVisitor.visit(isoGridSquare1, isoGridSquare0)) {
                    return lOSVisitor.getResult();
                }

                isoGridSquare0 = isoGridSquare1;
            }
        } else {
            float float4 = (float)int3 / (float)int0;
            float float5 = (float)int6 / (float)int0;
            float0 += (float)int5;
            float1 += (float)int7;
            int0 = int0 < 0 ? -1 : 1;
            float4 *= (float)int0;
            float5 *= (float)int0;

            while (int2 != int1) {
                int2 += int0;
                float0 += float4;
                float1 += float5;
                IsoGridSquare isoGridSquare2 = isoCell.getGridSquare((int)float0, int2, (int)float1);
                if (lOSVisitor.visit(isoGridSquare2, isoGridSquare0)) {
                    return lOSVisitor.getResult();
                }

                isoGridSquare0 = isoGridSquare2;
            }
        }

        return LosUtil.TestResults.Clear;
    }

    private IsoWindow getWindowBetween(int int0, int int1, int int2, int int3, int int4) {
        this.windowVisitor.init();
        this.los(int0, int1, int2, int3, int4, this.windowVisitor);
        return this.windowVisitor.window;
    }

    private IsoWindow getWindowBetween(IsoMovingObject isoMovingObject0, IsoMovingObject isoMovingObject1) {
        return this.getWindowBetween(
            (int)isoMovingObject0.x, (int)isoMovingObject0.y, (int)isoMovingObject1.x, (int)isoMovingObject1.y, (int)isoMovingObject0.z
        );
    }

    private boolean isWindowBetween(IsoMovingObject isoMovingObject0, IsoMovingObject isoMovingObject1) {
        return this.getWindowBetween(isoMovingObject0, isoMovingObject1) != null;
    }

    private void smashWindowBetween(IsoGameCharacter isoGameCharacter, IsoMovingObject isoMovingObject, HandWeapon handWeapon) {
        IsoWindow isoWindow = this.getWindowBetween(isoGameCharacter, isoMovingObject);
        if (isoWindow != null) {
            isoWindow.WeaponHit(isoGameCharacter, handWeapon);
        }
    }

    public void changeWeapon(HandWeapon weapon, IsoGameCharacter owner) {
        if (weapon != null && weapon.isUseSelf()) {
            owner.getInventory().setDrawDirty(true);

            for (InventoryItem inventoryItem : owner.getInventory().getItems()) {
                if (inventoryItem != weapon
                    && inventoryItem instanceof HandWeapon
                    && inventoryItem.getType() == weapon.getType()
                    && inventoryItem.getCondition() > 0) {
                    if (owner.getPrimaryHandItem() == weapon && owner.getSecondaryHandItem() == weapon) {
                        owner.setPrimaryHandItem(inventoryItem);
                        owner.setSecondaryHandItem(inventoryItem);
                    } else if (owner.getPrimaryHandItem() == weapon) {
                        owner.setPrimaryHandItem(inventoryItem);
                    } else if (owner.getSecondaryHandItem() == weapon) {
                        owner.setSecondaryHandItem(inventoryItem);
                    }

                    return;
                }
            }
        }

        if (weapon == null || weapon.getCondition() <= 0 || weapon.isUseSelf()) {
            HandWeapon handWeapon = (HandWeapon)owner.getInventory().getBestWeapon(owner.getDescriptor());
            owner.setPrimaryHandItem(null);
            if (owner.getSecondaryHandItem() == weapon) {
                owner.setSecondaryHandItem(null);
            }

            if (handWeapon != null && handWeapon != owner.getPrimaryHandItem() && handWeapon.getCondition() > 0) {
                owner.setPrimaryHandItem(handWeapon);
                if (handWeapon.isTwoHandWeapon() && owner.getSecondaryHandItem() == null) {
                    owner.setSecondaryHandItem(handWeapon);
                }
            }
        }
    }

    private void setParameterCharacterHitResult(IsoGameCharacter isoGameCharacter, IsoZombie isoZombie, long _long) {
        if (_long != 0L) {
            byte _byte = 0;
            if (isoZombie != null) {
                if (isoZombie.isDead()) {
                    _byte = 2;
                } else if (isoZombie.isKnockedDown()) {
                    _byte = 1;
                }
            }

            isoGameCharacter.getEmitter().setParameterValue(_long, FMODManager.instance.getParameterDescription("CharacterHitResult"), (float)_byte);
        }
    }

    public static class CustomComparator implements Comparator<HitInfo> {
        public int compare(HitInfo o1, HitInfo o2) {
            float float0 = o1.distSq;
            float float1 = o2.distSq;
            IsoZombie isoZombie0 = Type.tryCastTo(o1.getObject(), IsoZombie.class);
            IsoZombie isoZombie1 = Type.tryCastTo(o2.getObject(), IsoZombie.class);
            if (isoZombie0 != null && isoZombie1 != null) {
                boolean boolean0 = SwipeStatePlayer.isProne(isoZombie0);
                boolean boolean1 = SwipeStatePlayer.isProne(isoZombie1);
                boolean boolean2 = isoZombie0.isCurrentState(ZombieGetUpState.instance());
                boolean boolean3 = isoZombie1.isCurrentState(ZombieGetUpState.instance());
                if (boolean2 && !boolean3 && boolean1) {
                    return -1;
                }

                if (!boolean2 && boolean0 && boolean3) {
                    return 1;
                }

                if (boolean0 && boolean1) {
                    if (isoZombie0.isCrawling() && !isoZombie1.isCrawling()) {
                        return -1;
                    }

                    if (!isoZombie0.isCrawling() && isoZombie1.isCrawling()) {
                        return 1;
                    }
                }
            }

            if (float0 > float1) {
                return 1;
            } else {
                return float1 > float0 ? -1 : 0;
            }
        }
    }

    private interface LOSVisitor {
        boolean visit(IsoGridSquare var1, IsoGridSquare var2);

        LosUtil.TestResults getResult();
    }

    private static final class WindowVisitor implements SwipeStatePlayer.LOSVisitor {
        LosUtil.TestResults test;
        IsoWindow window;

        void init() {
            this.test = LosUtil.TestResults.Clear;
            this.window = null;
        }

        @Override
        public boolean visit(IsoGridSquare isoGridSquare1, IsoGridSquare isoGridSquare0) {
            if (isoGridSquare1 != null && isoGridSquare0 != null) {
                boolean boolean0 = true;
                boolean boolean1 = false;
                LosUtil.TestResults testResults = isoGridSquare1.testVisionAdjacent(
                    isoGridSquare0.getX() - isoGridSquare1.getX(),
                    isoGridSquare0.getY() - isoGridSquare1.getY(),
                    isoGridSquare0.getZ() - isoGridSquare1.getZ(),
                    boolean0,
                    boolean1
                );
                if (testResults == LosUtil.TestResults.ClearThroughWindow) {
                    IsoWindow isoWindow = isoGridSquare1.getWindowTo(isoGridSquare0);
                    if (this.isHittable(isoWindow) && isoWindow.TestVision(isoGridSquare1, isoGridSquare0) == IsoObject.VisionResult.Unblocked) {
                        this.window = isoWindow;
                        return true;
                    }
                }

                if (testResults != LosUtil.TestResults.Blocked
                    && this.test != LosUtil.TestResults.Clear
                    && (testResults != LosUtil.TestResults.ClearThroughWindow || this.test != LosUtil.TestResults.ClearThroughOpenDoor)) {
                    if (testResults == LosUtil.TestResults.ClearThroughClosedDoor && this.test == LosUtil.TestResults.ClearThroughOpenDoor) {
                        this.test = testResults;
                    }
                } else {
                    this.test = testResults;
                }

                return this.test == LosUtil.TestResults.Blocked;
            } else {
                return false;
            }
        }

        @Override
        public LosUtil.TestResults getResult() {
            return this.test;
        }

        boolean isHittable(IsoWindow isoWindow) {
            if (isoWindow == null) {
                return false;
            } else {
                return isoWindow.isBarricaded() ? true : !isoWindow.isDestroyed() && !isoWindow.IsOpen();
            }
        }
    }
}
